package org.biouno.unochoice;

import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.cloudbees.plugins.credentials.common.StandardCredentials;
import hudson.EnvVars;
import hudson.Extension;
import hudson.model.*;
import hudson.plugins.git.GitException;
import hudson.plugins.git.GitTool;
import hudson.util.ListBoxModel;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.eclipse.jgit.lib.ObjectId;
import org.jenkinsci.plugins.gitclient.Git;
import org.jenkinsci.plugins.gitclient.GitClient;
import org.kohsuke.stapler.*;
import org.kohsuke.stapler.interceptor.RequirePOST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import com.nirima.jenkins.plugins.docker.DockerCloud;
import com.nirima.jenkins.plugins.docker.DockerTemplate;
import static org.biouno.unochoice.UserRemoteConfig.DescriptorImpl.lookupCredentials;


@Extension
public class DataBaseApi implements RootAction {

    private static final Logger log = LoggerFactory.getLogger(DataBaseApi.class);

    @Override
    public String getIconFileName() {
        return "gear.png"; // 图标文件
    }

    @Override
    public String getDisplayName() {
        return "Database Custom API"; // 显示名称
    }

    @Override
    public String getUrlName() {
        return "database"; // URL 路径
    }

    // 自定义 HTTP 接口
    public HttpResponse doHello(@QueryParameter String name) {
        String message = "Hello, " + (name != null ? name : "World") + "!";
        return HttpResponses.plainText(message);
    }

    public HttpResponse doFillBranchItems(@AncestorInPath Item item, StaplerRequest request) {
        ListBoxModel r = new ListBoxModel();
        try {
            String contentType = request.getContentType();
            String url = null, defaultBranch = null, credentialsId = null;
            // 根据 Content-Type 处理请求
            if ("application/json".equals(contentType)) {
                // 处理 JSON 数据
                String jsonData = request.getReader().lines().collect(Collectors.joining());
                JSONObject jsonObject = JSONObject.fromObject(jsonData);
                url = jsonObject.getString("url");
                defaultBranch = jsonObject.getString("defaultBranch");
                credentialsId = jsonObject.getString("credentialsId");
            } else if ("application/x-www-form-urlencoded".equals(contentType)) {
                url = request.getParameter("url");
                defaultBranch = request.getParameter("defaultBranch");
                credentialsId = request.getParameter("credentialsId");
            }
            // Normally this permission is hidden and implied by Item.CONFIGURE, so from a view-only form you will not be able to use this check.
            // (TODO under certain circumstances being granted only USE_OWN might suffice, though this presumes a fix of JENKINS-31870.)
            if (item == null && !Jenkins.get().hasPermission(Jenkins.ADMINISTER) ||
                    item != null && !item.hasPermission(CredentialsProvider.USE_ITEM)) {
                System.err.println("none hasPermission");
                return r;
            }
            if (url == null || url.indexOf('$') >= 0) {
                // set by variable, can't validate
                System.err.println("url error");
                return r;
            }

            // get git executable on controller
            EnvVars environment;
            Jenkins jenkins = Jenkins.get();
            if (item instanceof Job<?, ?> job) {
                environment = job.getEnvironment(jenkins, TaskListener.NULL);
            } else {
                Computer computer = jenkins.toComputer();
                environment = computer == null ? new EnvVars() : computer.buildEnvironment(TaskListener.NULL);
            }

            GitClient git = Git.with(TaskListener.NULL, environment)
                    .using(GitTool.getDefaultInstallation().getGitExe())
                    .getClient();
            StandardCredentials credential = lookupCredentials(item, credentialsId, url);
            git.clearCredentials();
            git.addCredentials(url, credential);
            git.addDefaultCredentials(credential);
            try {
                Map<String, ObjectId> branchs = git.getRemoteReferences(url, "refs/heads/*", false, false);
                Map<String, ObjectId> release_tags = git.getRemoteReferences(url, "refs/tags/*", false, false);
                AtomicReference<String> ci = new AtomicReference<>("");
                AtomicReference<String> lastci = new AtomicReference<>("");
                release_tags.keySet().forEach(branch -> {
                    String b = branch.replace("refs/tags/", "");
                    if (b.indexOf("ci_") == 0) {
                        ci.set(b);
                    } else if (b.indexOf("lastci_") == 0) {
                        lastci.set(b);
                    } else {
                        r.add(b + "<tag>", b);
                    }
                });


                branchs.keySet().forEach(branch -> {
                    String b = branch.replace("refs/heads/", "");
                    r.add(b + "<branch>", b);
                });
                log.info("ci:{},lastci:{}",ci.get(),lastci.get());
                if (lastci.get() != "") {
                    ListBoxModel.Option elementData = new ListBoxModel.Option(lastci.get() + "<tag>", lastci.get());
                    if (ci.get().equals("")) elementData.selected = true;
                    r.add(0, elementData);
                }
                if (ci.get() != "") {
                    ListBoxModel.Option elementData = new ListBoxModel.Option(ci.get() + "<tag>", ci.get());
                    elementData.selected = true;
                    r.add(0, elementData);
                }
            } catch (GitException e) {
                e.printStackTrace();
                System.err.println("credentialsId:" + credentialsId);
                return r;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return r;
    }

    public HttpResponse doJobName() {
        Jenkins.get().getJobNames();
        JSONObject response = new JSONObject();
        try {
            final StaplerRequest2 currentRequest = Stapler.getCurrentRequest2();
            if (currentRequest != null) {
                final Ancestor ancestor = currentRequest.findAncestor(AbstractItem.class);
                if (ancestor != null) {
                    final Object o = ancestor.getObject();
                    if (o instanceof AbstractItem) {
                        response.put("success", true);
                        response.put("jobName", ((AbstractItem) o).getFullName());
                    }
                }
            }
        } catch (Exception e) {
            response.put("success", false);
        }
        return HttpResponses.text(response.toString());
    }

    public HttpResponse doNodes() {
        JSONObject response = new JSONObject();
        try {
            List<String> list=new ArrayList<>();
            Jenkins.getInstance().getNodes().forEach(node -> {
                System.err.println("node:"+node.getDisplayName());
                node.getNodeProperties().forEach(nodeProperty -> {
                    System.err.println("nodeProperty:"+nodeProperty.getClass().getName());
                });
                node.getAssignedLabels().forEach(label -> {
                    System.err.println("label:"+label.getDisplayName());
                    list.add(label.getDisplayName());
                });
            });
            Jenkins jenkins = Jenkins.getInstance();
            if (jenkins != null) {
                for (Object cloud : jenkins.clouds) {
                    if (cloud instanceof DockerCloud) {
                        DockerCloud dockerCloud = (DockerCloud) cloud;
                        for (DockerTemplate template : dockerCloud.getTemplates()) {
                            System.out.println("Template Name: " + template.getName() +
                                    ", Labels: " + template.getLabelString());
                            list.add(template.getLabelString());
                        }
                    }
                }
            }
            response.put("data", list);
            response.put("success", true);
        } catch (Exception e) {
            response.put("success", false);
        }
        return HttpResponses.text(response.toString());
    }


    public HttpResponse doExecuteQuery(StaplerRequest request) {
        JSONObject response = new JSONObject();
        try {
            String contentType = request.getContentType();
            String sql = null;
            // 根据 Content-Type 处理请求
            if ("application/json".equals(contentType)) {
                // 处理 JSON 数据
                String jsonData = request.getReader().lines().collect(Collectors.joining());
                JSONObject jsonObject = JSONObject.fromObject(jsonData);
                sql = jsonObject.getString("sql");
            } else if ("application/x-www-form-urlencoded".equals(contentType)) {
                sql = request.getParameter("sql");
            }
            System.err.println("sql:" + sql);
            List<HashMap<String, Object>> list = MySQLDatabaseUtils.executeQuery(sql);
            response.put("data", list);
            response.put("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            response.put("success", false);
        }
        // 返回 JSON 响应
        return HttpResponses.text(response.toString());
    }

    @RequirePOST
    public HttpResponse doExecuteSql(StaplerRequest request) {
        JSONObject response = new JSONObject();
        try {
            String contentType = request.getContentType();
            String sql = null;
            // 根据 Content-Type 处理请求
            if ("application/json".equals(contentType)) {
                // 处理 JSON 数据
                String jsonData = request.getReader().lines().collect(Collectors.joining());
                JSONObject jsonObject = JSONObject.fromObject(jsonData);
                sql = jsonObject.getString("sql");
                // 处理 jsonData...
            } else if ("application/x-www-form-urlencoded".equals(contentType)) {
                sql = request.getParameter("sql");
            }
            System.err.println("sql:" + sql);
            boolean res = MySQLDatabaseUtils.executeSql(sql);
            response.put("data", res);
            response.put("success", res);
        } catch (Exception e) {
            e.printStackTrace();
            response.put("success", false);
        }

        // 返回 JSON 响应
        return HttpResponses.text(response.toString());
    }
}
